#ifndef VIRTUALCANVASMANAGER_H
#define VIRTUALCANVASMANAGER_H

#include <QObject>
#include <QImage>
#include <QSize>
#include <QCache>
#include <QMutex>
#include <QTimer>
#include <QElapsedTimer>
#include <memory>

#include "processingsettings.h"

// 前向声明
struct ProcessingSettings;

/**
 * 虚拟画布管理器
 * 职责：管理不同DPI的虚拟画布创建、缓存和清理
 *
 * Martin Fowler重构原则：
 * - Replace Method: 用对象方法替换静态方法调用
 * - Extract Class: 从渲染逻辑中提取缓存管理职责
 * - Introduce Parameter Object: 使用RenderContext统一渲染参数
 *
 * 设计模式：
 * - Manager Pattern: 统一管理虚拟画布的生命周期
 * - Cache Pattern: LRU缓存策略，支持内存限制
 * - Observer Pattern: 发出缓存状态变化信号
 */
class VirtualCanvasManager : public QObject
{
    Q_OBJECT

public:
    /**
     * 渲染上下文
     * 重构原则：Introduce Parameter Object - 将相关渲染参数组织到一个对象中
     */
    struct RenderContext {
        QImage content;                 // 源内容图像
        ProcessingSettings settings;    // 处理设置
        int pageNumber;                 // 页码
        int totalPages;                 // 总页数
        double targetDpi;               // 目标DPI
        QSizeF pageSizeMM;             // 页面物理尺寸（毫米）
        bool enableDecorations;         // 是否启用装饰（页码、边距等）
        QString customIdentifier;       // 自定义标识符（用于额外的缓存区分）

        RenderContext();

        /**
         * 检查上下文是否有效
         * @return 如果上下文有效返回true
         */
        bool isValid() const;

        /**
         * 生成上下文的唯一标识
         * @return 上下文标识字符串
         */
        QString generateIdentifier() const;

        /**
         * 获取调试信息
         * @return 格式化的调试信息
         */
        QString getDebugInfo() const;
    };

    /**
     * 缓存统计信息
     */
    struct CacheStats {
        int totalItems;              // 总缓存项数
        qint64 totalSizeBytes;       // 总缓存大小（字节）
        qint64 maxSizeBytes;         // 最大缓存大小（字节）
        int hitCount;                // 缓存命中次数
        int missCount;               // 缓存未命中次数
        double hitRatio;             // 命中率
        QStringList recentKeys;      // 最近访问的键

        CacheStats();
        QString toString() const;
    };

public:
    explicit VirtualCanvasManager(QObject* parent = nullptr);
    ~VirtualCanvasManager() override;

    // === 主要功能接口 ===

    /**
     * 获取或创建虚拟画布
     * 这是主要的接口方法，会自动处理缓存逻辑
     * @param context 渲染上下文
     * @return 渲染好的虚拟画布
     */
    QImage getOrCreateVirtualCanvas(const RenderContext& context);

    /**
     * 强制创建新的虚拟画布（忽略缓存）
     * @param context 渲染上下文
     * @return 新创建的虚拟画布
     */
    QImage createVirtualCanvas(const RenderContext& context);

    /**
     * 预创建虚拟画布（异步）
     * 用于预加载，提高后续渲染性能
     * @param context 渲染上下文
     */
    void preCreateVirtualCanvas(const RenderContext& context);

    // === 缓存管理 ===

    /**
     * 清除所有缓存
     */
    void clearCache();

    /**
     * 清除指定DPI的缓存
     * @param dpi 要清除的DPI值
     */
    void clearCacheForDpi(double dpi);

    /**
     * 清除指定页面的缓存
     * @param pageNumber 页码
     */
    void clearCacheForPage(int pageNumber);

    /**
     * 清除过期缓存
     * @param maxAgeMs 最大缓存时间（毫秒）
     */
    void clearExpiredCache(qint64 maxAgeMs = 300000); // 默认5分钟

    // === 配置管理 ===

    /**
     * 设置最大缓存大小
     * @param maxSizeMB 最大缓存大小（MB）
     */
    void setMaxCacheSize(qint64 maxSizeMB);

    /**
     * 获取最大缓存大小
     * @return 最大缓存大小（MB）
     */
    qint64 getMaxCacheSize() const;

    /**
     * 设置缓存清理策略
     * @param enableAutoCleanup 是否启用自动清理
     * @param cleanupIntervalMs 清理间隔（毫秒）
     */
    void setCacheCleanupPolicy(bool enableAutoCleanup, int cleanupIntervalMs = 60000);

    // === 统计和监控 ===

    /**
     * 获取当前缓存大小
     * @return 当前缓存大小（字节）
     */
    qint64 getCurrentCacheSize() const;

    /**
     * 获取缓存统计信息
     * @return 缓存统计
     */
    CacheStats getCacheStats() const;

    /**
     * 获取缓存使用率
     * @return 缓存使用率（0.0-1.0）
     */
    double getCacheUsageRatio() const;

    /**
     * 检查是否有指定上下文的缓存
     * @param context 渲染上下文
     * @return 如果有缓存返回true
     */
    bool hasCachedCanvas(const RenderContext& context) const;

signals:
    /**
     * 缓存更新时发出
     * @param currentSize 当前缓存大小（字节）
     * @param maxSize 最大缓存大小（字节）
     */
    void cacheUpdated(qint64 currentSize, qint64 maxSize);

    /**
     * 缓存命中时发出
     * @param contextId 上下文标识
     */
    void cacheHit(const QString& contextId);

    /**
     * 缓存未命中时发出
     * @param contextId 上下文标识
     */
    void cacheMiss(const QString& contextId);

    /**
     * 虚拟画布创建完成时发出
     * @param context 渲染上下文
     * @param canvas 创建的画布
     * @param createTimeMs 创建耗时（毫秒）
     */
    void canvasCreated(const RenderContext& context, const QImage& canvas, qint64 createTimeMs);

    /**
     * 缓存清理完成时发出
     * @param clearedCount 清理的项目数量
     * @param freedBytes 释放的字节数
     */
    void cacheCleanupCompleted(int clearedCount, qint64 freedBytes);

private slots:
    /**
     * 自动缓存清理
     */
    void performAutoCleanup();

private:
    // === 核心渲染方法 ===

    /**
     * 创建虚拟画布的核心实现
     * @param context 渲染上下文
     * @return 创建的虚拟画布
     */
    QImage doCreateVirtualCanvas(const RenderContext& context);

    /**
     * 计算虚拟画布尺寸
     * @param context 渲染上下文
     * @return 画布尺寸
     */
    QSize calculateVirtualCanvasSize(const RenderContext& context) const;

    /**
     * 渲染页面内容到画布
     * @param painter 绘制器
     * @param canvasSize 画布尺寸
     * @param context 渲染上下文
     */
    void renderPageContent(QPainter& painter, const QSize& canvasSize, const RenderContext& context);

    /**
     * 渲染页面装饰（页码、边距等）
     * @param painter 绘制器
     * @param canvasSize 画布尺寸
     * @param context 渲染上下文
     */
    void renderPageDecorations(QPainter& painter, const QSize& canvasSize, const RenderContext& context);

    /**
     * 计算内容在画布中的位置
     * @param contentSize 内容尺寸
     * @param canvasSize 画布尺寸
     * @param context 渲染上下文
     * @return 内容矩形区域
     */
    QRect calculateContentRect(const QSize& contentSize, const QSize& canvasSize,
                              const RenderContext& context) const;

    // === 缓存相关方法 ===

    /**
     * 生成缓存键
     * @param context 渲染上下文
     * @return 缓存键字符串
     */
    QString generateCacheKey(const RenderContext& context) const;

    /**
     * 检查缓存中是否存在指定键
     * @param cacheKey 缓存键
     * @return 如果存在返回true
     */
    bool hasCacheKey(const QString& cacheKey) const;

    /**
     * 从缓存获取画布
     * @param cacheKey 缓存键
     * @return 缓存的画布，如果不存在返回空图像
     */
    QImage getCachedCanvas(const QString& cacheKey) const;

    /**
     * 将画布存入缓存
     * @param cacheKey 缓存键
     * @param canvas 要缓存的画布
     */
    void setCachedCanvas(const QString& cacheKey, const QImage& canvas);

    /**
     * 更新缓存访问记录
     * @param cacheKey 缓存键
     * @param isHit 是否命中
     */
    void updateCacheStats(const QString& cacheKey, bool isHit);

    /**
     * 计算图像的内存大小
     * @param image 图像
     * @return 内存大小（字节）
     */
    qint64 calculateImageSize(const QImage& image) const;

    /**
     * 执行LRU清理
     * @param targetSize 目标缓存大小
     * @return 清理的项目数量
     */
    int performLRUCleanup(qint64 targetSize);

private:
    // === 缓存相关成员 ===
    struct CacheItem {
        QImage canvas;              // 画布图像
        qint64 createTime;          // 创建时间（毫秒）
        qint64 lastAccessTime;      // 最后访问时间（毫秒）
        int accessCount;            // 访问次数
        qint64 sizeBytes;          // 图像大小（字节）

        CacheItem() : createTime(0), lastAccessTime(0), accessCount(0), sizeBytes(0) {}
        CacheItem(const QImage& img, qint64 size);
    };

    mutable QMutex m_cacheMutex;                    // 缓存互斥锁
    QHash<QString, CacheItem> m_cache;              // 主缓存容器
    qint64 m_maxCacheSizeBytes;                     // 最大缓存大小（字节）
    qint64 m_currentCacheSizeBytes;                 // 当前缓存大小（字节）

    // === 统计信息 ===
    mutable int m_cacheHitCount;                    // 缓存命中次数
    mutable int m_cacheMissCount;                   // 缓存未命中次数
    mutable QStringList m_recentAccessKeys;        // 最近访问的键（用于LRU）

    // === 自动清理 ===
    QTimer* m_cleanupTimer;                         // 自动清理计时器
    bool m_autoCleanupEnabled;                      // 是否启用自动清理
    int m_cleanupIntervalMs;                        // 清理间隔（毫秒）

    // === 常量定义 ===
    static constexpr qint64 DEFAULT_MAX_CACHE_MB = 200;    // 默认最大缓存（MB）
    static constexpr int DEFAULT_CLEANUP_INTERVAL_MS = 60000;  // 默认清理间隔（60秒）
    static constexpr int MAX_RECENT_KEYS = 100;            // 最大最近访问键数量
    static constexpr qint64 CACHE_EXPIRED_MS = 300000;     // 缓存过期时间（5分钟）
};

#endif // VIRTUALCANVASMANAGER_H